﻿using Dispatcher.Core.Mail.Models;
using MiniFox;
using MiniFox.Components;
using MiniFox.Mail;
using MiniFox.Platform.Applications.Auth;
using MiniFox.Platform.File.Models;
using MiniFox.Utility;
using System.Net.Mail;

namespace Dispatcher.Core.Mail
{
    [AutoRegister, SpareComponent(typeof(MailEngineService))]
    public class MailEngineService : EngineServiceBase
    {
        /// <summary>
        /// 
        /// </summary>
        public MailEngineService(SystemPrincipal principal) : base(principal)
        {
        }
        [AutoWired]
        public IMailProvider Provider { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileDatas"></param>
        /// <returns></returns>
        protected virtual Attachment[] GetAttachments(IEnumerable<FileData> fileDatas)
        {
            if (fileDatas == null || fileDatas.Count() <= 0)
                return null;
            List<Attachment> attachmentList = [];
            Parallel.ForEach(fileDatas, fileData =>
            {
                Attachment attachment = new Attachment(new MemoryStream(fileData.Data), fileData.FileName, fileData.ContentType);
                attachmentList.Add(attachment);
            });
            return attachmentList.ToArray();
        }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="sendRequest"></param>
        ///// <returns></returns>
        //public MailSendResponse Send(MailSendRequest sendRequest)
        //{
        //    string messageId = SequenceGUID.NewGUID();
        //    var mailService = MailServiceFactory.CreateInstance(sendRequest.AccountName);
        //    string body = GetBodyContentAsync(sendRequest);
        //    IEnumerable<FileData> fileDatas = GetAttachments(sendRequest.AttachmentBatchID);
        //    var attachments = GetAttachments(fileDatas);

        //    mailService.MailSent += (sender, e) =>
        //    {
        //        this.Provider.SentLog(messageId, sendRequest, e.MailMessage, e.IsAsync, e.Cancelled);
        //        this.AttachmentProvider.SetAttachment(messageId, fileDatas);
        //    };
        //    mailService.MailError += (sender, e) =>
        //    {
        //        this.Provider.FailLog(messageId, sendRequest, e.MailMessage, e.IsAsync, e.Error);
        //        this.AttachmentProvider.SetAttachment(messageId, fileDatas);
        //    };
        //    var users = this.GetUsers(sendRequest.Receiver);
        //    var receivers = users.Select(u => u.SecEmail).ToArray();
        //    users = this.GetUsers(sendRequest.CCList);
        //    var cclist = users == null ? null : users.Select(u => u.SecEmail).ToArray();
        //    mailService.SendMail(sendRequest.Title, body, true, receivers, cclist, attachments);

        //    return new MailSendResponse
        //    {
        //        MessageId = messageId,
        //        SendTime = DateTime.Now
        //    };
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sendRequest"></param>
        /// <returns></returns>
        public async Task<MailSendResponse> SendAsync(MailSendRequest sendRequest)
        {
            string messageId = SequenceGUID.NewGUID();
            var mailService = MailServiceFactory.CreateInstance(sendRequest.AccountName);
            IEnumerable<FileData> fileDatas = GetAttachments(sendRequest.Files);
            var attachments = GetAttachments(fileDatas);

            mailService.MailSent += (sender, e) =>
            {
                this.Provider.SentLog(messageId, sendRequest, e.MailMessage, e.IsAsync, e.Cancelled);
                this.AttachmentProvider.SetAttachment(messageId, fileDatas);
            };
            mailService.MailError += (sender, e) =>
            {
                this.Provider.FailLog(messageId, sendRequest, e.MailMessage, e.IsAsync, e.Error);
                this.AttachmentProvider.SetAttachment(messageId, fileDatas);
            };
            var users = this.GetUsers(sendRequest.Receiver);
            var receivers = users.Select(u => u.SecEmail).ToArray();
            users = this.GetUsers(sendRequest.CCList);
            var cclist = users.Select(u => u.SecEmail).ToArray();
            string body = await GetBodyContentAsync(sendRequest);
            await mailService.SendMailAsync(sendRequest.Title, body, true, receivers, cclist, attachments);

            return new ()
            {
                MessageId = messageId,
                SendTime = DateTime.Now
            };
        }

    }
}
